package com.youlu.campus.service.ca.impl;

import com.alibaba.fastjson.JSON;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.CaOrganization;
import com.youlu.campus.entity.UserCaOrg;
import com.youlu.campus.entity.UserCaRecord;
import com.youlu.campus.entity.VO.req.UserCaQueryVO;
import com.youlu.campus.entity.system.UserDataPermission;
import com.youlu.campus.service.activity.impl.PlatformOtherActivityService;
import com.youlu.campus.service.order.OrderService;
import com.youlu.campus.service.system.UserDataPermissionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;

@Slf4j
@Service
public class UserCaRecordService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private UserDataPermissionService userDataPermissionService;
    @Lazy
    @Autowired
    private OrderService orderService;
    @Lazy
    @Autowired
    private PlatformOtherActivityService platformOtherActivityService;


    public Page<UserCaRecord> userCaQuery(UserCaQueryVO userCaQuery) {
        PageRequest pageRequest = PageRequest.of(userCaQuery.getPage() - 1, userCaQuery.getPageSize());
        UserDataPermission userDataPermission = userDataPermissionService.findOne(userCaQuery.getUserId());
        if (Objects.isNull(userDataPermission) || CollectionUtils.isEmpty(userDataPermission.getActivityId())) {
            return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> 0);
        }

        Query query = new Query();
        query.addCriteria(Criteria.where("activityId").in(userDataPermission.getActivityId()));
        String keywords = userCaQuery.getKeywords();
        boolean chioced = false;
        if (StringUtils.isNotBlank(keywords)) {
            query.addCriteria(new Criteria().orOperator(
                    Criteria.where("userName").is(keywords), Criteria.where("certificateNo").is(keywords)));
            chioced = true;
        }
        long count;
        if (chioced) {
            count = this.mongoTemplate.count(query, UserCaRecord.class);
        } else {
            count = 10000L;
        }
        if (count == 0) {
            return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> 0);
        }
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<UserCaRecord> list = this.mongoTemplate.find(query.with(pageRequest), UserCaRecord.class);
        list.stream().forEach(userCaRecord -> {
            userCaRecord.setLevelName("");
            userCaRecord.setCaName("");
            userCaRecord.setCaOrg(null);
            userCaRecord.setCaTime("");
        });
        return PageableExecutionUtils.getPage(list, pageRequest, () -> count);
    }

    public Page<UserCaRecord> list(UserCaQueryVO userCaQuery) {
        Query query = new Query();
        boolean choiced = false;
        if (StringUtils.isNotBlank(userCaQuery.getUserName())) {
            Pattern pattern = Pattern.compile("^.*" + userCaQuery.getUserName() + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("userName").regex(pattern));
            choiced = true;
        }

        if (StringUtils.isNotBlank(userCaQuery.getMobile())) {
            //Pattern pattern = Pattern.compile("^.*" + userCaQuery.getMobile() + ".*$", Pattern.CASE_INSENSITIVE);
            query.addCriteria(Criteria.where("mobile").is(userCaQuery.getMobile()));
            choiced = true;
        }
        if (StringUtils.isNotBlank(userCaQuery.getCertificateNo())) {
            query.addCriteria(Criteria.where("certificateNo").is(userCaQuery.getCertificateNo()));
            choiced = true;
        }
        long count = 0;
        if (!choiced) {
            count = 100L;
        } else {
            count = this.mongoTemplate.count(query, UserCaRecord.class);
        }
        Long total = count;
        PageRequest pageRequest = PageRequest.of(userCaQuery.getPage() - 1, userCaQuery.getPageSize());
        if (count == 0) {
            return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> 0);
        }
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        List<UserCaRecord> list = this.mongoTemplate.find(query.with(pageRequest), UserCaRecord.class);
        return PageableExecutionUtils.getPage(list, pageRequest, () -> total);
    }

    public void saveBatch(List<UserCaRecord> list) {

        list.stream().forEach(caOrg -> {
            String importCaOrgId = caOrg.getImportCaOrgId();
            if (StringUtils.isBlank(importCaOrgId)) {
                return;
            }
            if (StringUtils.isBlank(caOrg.getMobile())) {
                log.error("手机号不能为空 mobile:{}", caOrg.getMobile());
                throw new BusinessException("手机号不能为空");
            }
            if (strIsWhitespace(caOrg.getMobile())) {
                log.error("手机号不能有空格 mobile:{}", caOrg.getMobile());
                throw new BusinessException("手机号不能有空格");
            }
            if (StringUtils.isBlank(caOrg.getCertificateNo())) {
                log.error("证书编号不能为空 certificateNo:{}", caOrg.getCertificateNo());
                throw new BusinessException("证书编号不能为空");
            }
            if (strIsWhitespace(caOrg.getCertificateNo())) {
                log.error("证书编号不能有空格 certificateNo:{}", caOrg.getCertificateNo());
                throw new BusinessException("证书编号不能有空格");
            }
            if (StringUtils.isBlank(caOrg.getUserName())) {
                log.error("姓名不能为空 name:{}", caOrg.getUserName());
                throw new BusinessException("姓名不能为空");
            }
            if (strIsWhitespace(caOrg.getUserName())) {
                log.error("姓名不能有空格 name:{}", caOrg.getUserName());
                throw new BusinessException("姓名不能有空格");
            }
            if (StringUtils.isBlank(caOrg.getLevelName())) {
                log.error("等级不能为空 levelName:{}", caOrg.getLevelName());
                throw new BusinessException("等级不能为空");
            }
            if (strIsWhitespace(caOrg.getLevelName())) {
                log.error("等级不能有空格 name:{}", caOrg.getLevelName());
                throw new BusinessException("等级不能有空格");
            }
            if (StringUtils.isBlank(caOrg.getUniversityName())) {
                log.error("学校不能为空 universityName:{}", caOrg.getUniversityName());
                throw new BusinessException("学校不能为空");
            }
            if (strIsWhitespace(caOrg.getUniversityName())) {
                log.error("学校不能有空格 universityName:{}", caOrg.getUniversityName());
                throw new BusinessException("学校不能有空格");
            }
            String[] importCaOrgIds = importCaOrgId.split(",");
            Query query = new Query();
            query.addCriteria(Criteria.where("id").in(importCaOrgIds));
            List<CaOrganization> organizationList = this.mongoTemplate.find(query, CaOrganization.class);
            if (!CollectionUtils.isEmpty(organizationList)) {
                UserCaOrg[] caOrgArray = new UserCaOrg[organizationList.size()];
                int index = 0;
                for (CaOrganization org : organizationList) {
                    UserCaOrg userCaOrg = new UserCaOrg();
                    userCaOrg.setCaOrganizationId(org.getId());
                    userCaOrg.setCaOrganizationName(org.getName());
                    userCaOrg.setStampImage(org.getStampImage());
                    caOrgArray[index] = userCaOrg;
                    index++;
                }
                caOrg.setCaOrg(caOrgArray);
            }
        });
        mongoTemplate.insertAll(list);
    }

    public UserCaRecord detail(String id) {
        return this.mongoTemplate.findById(id, UserCaRecord.class);
    }

    public void update(UserCaRecord updateCaRecord) {
        String id = updateCaRecord.getId();
        if (StringUtils.isBlank(id)) {
            return;
        }
        UserCaRecord userCaRecord = this.mongoTemplate.findById(id, UserCaRecord.class);
        if (Objects.isNull(updateCaRecord)) {
            throw new BusinessException("证书数据不存在");
        }
        BeanUtils.copyProperties(updateCaRecord, userCaRecord);
        this.mongoTemplate.save(userCaRecord);
        this.orderService.updateByMobileAndActivityId(userCaRecord.getMobile(), updateCaRecord.getMobile(),
                userCaRecord.getActivityId(), updateCaRecord.getUserName(), updateCaRecord.getUniversityId(),
                updateCaRecord.getUniversityName(), "");
        this.platformOtherActivityService.updateByMobileAndActivityId(userCaRecord.getMobile(), updateCaRecord.getMobile(),
                userCaRecord.getActivityId(), updateCaRecord.getUserName(), updateCaRecord.getUniversityId(),
                updateCaRecord.getUniversityName(), "");
    }

    public void remove(String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        this.mongoTemplate.remove(query, UserCaRecord.class);
    }

    public void update(String certificateNo, UserCaRecord updateCaRecord) {
        if (StringUtils.isBlank(certificateNo) || Objects.isNull(updateCaRecord)) {
            log.error(":>>> 证书编号或修改对象为空");
            return;
        }
        Query query = new Query().addCriteria(Criteria.where("certificateNo").is(certificateNo));
        Update update = new Update();
        if (StringUtils.isNotBlank(updateCaRecord.getCaName())) {
            update.set("caName", updateCaRecord.getCaName());
        }
        if (StringUtils.isNotBlank(updateCaRecord.getUniversityId())) {
            update.set("universityId", updateCaRecord.getUniversityId());
        }
        if (StringUtils.isNotBlank(updateCaRecord.getUniversityName())) {
            update.set("universityName", updateCaRecord.getUniversityName());
        }
        update.set("updatedTime", new Date());
        UpdateResult updateResult = mongoTemplate.updateMulti(query, update, UserCaRecord.class);
        log.info(":>>> 修改证书编号:{},修改信息:{},数量:{}", certificateNo, JSON.toJSON(updateCaRecord), updateResult.getModifiedCount());
    }

    public void updateByMobileAndActivityId(String mobile, String toMobile, String activityId,
                                            String name, String universityId, String universityName) {
        if (StringUtils.isBlank(mobile) || StringUtils.isBlank(activityId)) {
            return;
        }
        Query query = new Query().addCriteria(Criteria.where("mobile").is(mobile).and("activityId").is(activityId));
        Update update = new Update();
        Date date = new Date();
        boolean toUpdate = false;
        if (StringUtils.isNotBlank(name)) {
            update.set("userName", name);
            toUpdate = true;
        }
        if (StringUtils.isNotBlank(universityId)) {
            update.set("universityId", universityId);
            toUpdate = true;
        }
        if (StringUtils.isNotBlank(universityName)) {
            update.set("universityName", universityName);
            toUpdate = true;
        }
        if (!mobile.equals(toMobile)) {
            update.set("mobile", toMobile);
            toUpdate = true;
        }
        if (toUpdate) {
            update.set("updatedTime", date);
            mongoTemplate.updateMulti(query, update, UserCaRecord.class);
        }
    }

    public static boolean strIsWhitespace(String str) {
        for (int i = 0; i < str.length(); i++) {
            if (isWhitespace(str.charAt(i))) {
                return Boolean.TRUE;
            }
        }
        return Boolean.FALSE;
    }

    public static boolean isWhitespace(char ch) {
        if (ch == '　') {
            return true;
        }
        if (Character.isWhitespace(ch)) {
            return true;
        }
        return false;
    }


}
